package pay.serviceImpl;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import pay.common.ConstantFYJZH;
import pay.common.ConstantOrderStatus;
import pay.entity.ProductInfo;
import pay.entity.SysUser;
import pay.entity.Trade;
import pay.portal.web.message.PaybackOrderMsg;
import pay.service.*;
import pay.service.sys.ISysUser;
import pay.utils.BalanceUtils;
import pay.utils.DateUtil;
import pay.utils.FYApiUtil;
import pay.utils.JsonUtils;
import pay.utils.MapSortUtil;
import pay.utils.RedisCilent;
import pay.utils.StringHelper;
import pay.utils.WriteFileUtils;
import pay.utils.XmlUtils;

@Service
public class PaybackImpl implements IPayBack {
	
	protected Logger logger = LoggerFactory
			.getLogger(this.getClass().getName());
	
	@Value("${fy.mchntCd}")
	private String mchnt_cd;
	@Value("${fy.goldAccount.logsBaseUrl}")
	private String logsBaseUrl;
	@Value("${server.scheme}")
	private String serverScheme;
	@Value("${fy.goldAccount.baseUrl}")
	private String jzhBaseUrl;
	@Value("${fy.goldAccount.pathBaseUrl}")
	private String pathBaseUrl;// 测试环境为/jzh 生产无。
	@Value("${producer.host}")
	private String host;
	
	@Autowired
	private ISysUser userService;

	@Autowired
	private ITrade tradeService;

	@Autowired
	private IOrderHelper orderHelperService;
	
	@Autowired
	private IOrderJpa orderJpaService;

	@Autowired
	private IProduct productJPA;
	
	
	
	@Override
	public String getSSN(Long orderId) {
		
		String ctsLong = String.valueOf(System.currentTimeMillis());
		String cts = ctsLong.substring(ctsLong.length() - 4,
					ctsLong.length());
		String mchnt_txn_ssn = cts + orderId + ConstantFYJZH.MSSN_HK;
		
		logger.info("回款划拨, 根据orderId生成流水号， orderId={}， mchnt_txn_ssn={}",orderId,  mchnt_txn_ssn );
		return mchnt_txn_ssn;
	}

	
	@Override
	public Boolean payBack(String mchnt_txn_ssn) {
		logger.info("回款划拨 mchnt_txn_ssn = {}", mchnt_txn_ssn);
		
		String paybackOrderMsgStr = this.getPaybackRecordFromRedis(mchnt_txn_ssn);
		
		if(StringHelper.isEmpty(paybackOrderMsgStr)){
			logger.info("回款划拨, 流水号在redis中不存在，将停止回款划拨 mchnt_txn_ssn ={}", mchnt_txn_ssn);
			return false;
		}
		
		PaybackOrderMsg paybackOrderMsg =  JsonUtils.toBean(paybackOrderMsgStr, PaybackOrderMsg.class);
		
		logger.error("回款划拨 PaybackOrderMsg={} ", paybackOrderMsg.toString());
		
		Long orderId = paybackOrderMsg.getOrderId();
		
		String out_cust_no = paybackOrderMsg.getOutAccount();
		
		String in_cust_no = paybackOrderMsg.getInAccount();
		
		BigDecimal amt = paybackOrderMsg.getAmt();
		
		if(	orderId == null 
			|| amt == null
			|| StringHelper.isEmpty(out_cust_no )
			|| StringHelper.isEmpty(in_cust_no )
			|| StringHelper.isEmpty(mchnt_txn_ssn)){
			
			logger.error("订单回款参数检查，发现错误停止回款 orderId={}",orderId );
			return false;
		}
		
		SysUser user = userService.getByPhoneNum( in_cust_no);
		
		if(user == null ){
			logger.error("订单回款参数检查，发现错误, 用户不存在，停止回款， orderId={}",orderId );
			return false;
		}
		
		// 获取富友返回结果
		Boolean result = this.getPayBackResult(orderId, mchnt_txn_ssn, in_cust_no, out_cust_no,  amt);
		
		logger.info("回款划拨结果是 result={}, orderId={}", result,
				paybackOrderMsg.getOrderId());
		
		//根据回款划拨结果更新相关信息
		updPaybackResult(mchnt_txn_ssn, result);
		
		return result;
	}

	@Override
	public void addPaybackRecordIntoRedis(String mchnt_txn_ssn,
			String paybackOrderStr) {
		//首先将需要进行回款划拨的订单信息保存在redis中
		logger.info("订单回款划拨前，先将回拨信息保存在redis中， mchnt_txn_ssn={}，transferMsgStr={}", mchnt_txn_ssn,
				paybackOrderStr);
		RedisCilent.setString(mchnt_txn_ssn, paybackOrderStr, 172800);
		
	}

	@Override
	public String getPaybackRecordFromRedis(String mchnt_txn_ssn) {
		logger.info("从redis中 获取回款划拨订单信息 ， mchnt_txn_ssn={} ", mchnt_txn_ssn);
		
		String paybackOrderStr = RedisCilent.getString(mchnt_txn_ssn);
		return paybackOrderStr;
	}

	@Override
	public void delPaybackRecordFromRedis(String mchnt_txn_ssn) {
		logger.info("从redis中 删除回款划拨的订单信息 ， mchnt_txn_ssn={} ", mchnt_txn_ssn);
		RedisCilent.delKey(mchnt_txn_ssn);	
	}

	@Override
	public void addIntoTradeTable(Long orderId, Long userId, String login_id,
			BigDecimal amount, String mchnt_txn_ssn, String tradeDesc,
			String resp_code, String resp_desc) {
		
		logger.info("订单回款，调用方法addIntoTradeTable 将回款信息保存在trade表中 orderId={}，  mchnt_txn_ssn={} ", orderId, mchnt_txn_ssn); 
		Trade trade = new Trade();
		trade.setOrderId(orderId);
		trade.setUserId(userId);
		trade.setLogin_id(login_id);
		trade.setAmt(amount);
		trade.setCts(System.currentTimeMillis());
		trade.setMchnt_txn_ssn(mchnt_txn_ssn);
		trade.setFlowType(ConstantFYJZH.BALANCE_ADD);
		trade.setType(ConstantFYJZH.TRADE_TY_HK);
		trade.setTradeDesc(tradeDesc);
		trade.setResp_code(resp_code);
		trade.setResp_desc(resp_desc);

		//发送通知告知用户有错误信息
		if(resp_code.equals("0000") == false && tradeService.isExist(trade) == false){

			String prouctName = tradeService.getProductNameByTrade(trade);

			//短信内容
			String msg = "管理员您好！产品名称：" + prouctName + "，订单号：" + trade.getOrderId() + "，在回款拨时发生错误，请注意并查找原因！";

			//邮件标题
			String emailMsgTitle = prouctName + "回款划拨错误通知邮件-重要!!！";

			//邮件内容
			String emailMsgContent = msg + "/n" + trade.toString();

			tradeService.sendErrorMsg(msg, emailMsgTitle, emailMsgContent);
		}

		tradeService.save(trade);
}


	@Override
	public Boolean getPayBackResult(Long orderId, String mchnt_txn_ssn,
			String in_cust_no, String out_cust_no, BigDecimal amt) {
		
		Boolean result = false;
		
		SysUser user = userService.getByPhoneNum( in_cust_no);
		
		if(user == null ){
			logger.error("订单回款参数检查，发现错误, 用户不存在，停止回款， orderId={}",orderId );
			return false;
		}
		
		//校验参数是否正常
		if (StringHelper.isEmpty(mchnt_txn_ssn)
				|| StringHelper.isEmpty(out_cust_no)
				|| StringHelper.isEmpty(in_cust_no)
				|| amt == null) {
			logger.info("订单回款参数检查, 入参有空参数");
			return false;
		}
				
		
		String resultStr = sendPostToFY(mchnt_txn_ssn, out_cust_no, in_cust_no, amt);
		
		
		logger.info("回款划拨结果是 resultStr={} ", resultStr);
		String resultCode = XmlUtils.getVal(resultStr, "resp_code");
		
		logger.info("将回款信息添加到trade表中 orderId={}", orderId);
		addIntoTradeTable(orderId, user.getId(), user.getName(), amt, mchnt_txn_ssn, "回款", resultCode, ""); 
		
		logger.info("将回款信息添加到回款记录表中 orderId={}", orderId);
		writeFile(resultCode, orderId, in_cust_no, out_cust_no, amt, user.getId());
		
		
		if (StringHelper.isNotEmpty(resultCode) && resultCode.equals("0000")) {
			result = true;
			logger.info("回款划拨结果是  result={} ", result);
		}
		
		return result;
	}

	@Override
	public void writeFile(String responseCode, Long orderId,
			String in_cust_no, String out_cust_no, BigDecimal amt, Long userId) {
		try {
			amt = amt.divide(new BigDecimal(100));
			Long cts = System.currentTimeMillis();
			String log = DateUtil
					.transferLongToDate("yyyy-MM-dd HH:mm:ss", cts)
					+ "----金账户回款回调信息:  responseCode = "
					+ responseCode
					+ ",orderId = "
					+ orderId
					+ ",收款账户 = "
					+ in_cust_no
					+ ",付款账户 = "
					+ out_cust_no
					+ ",回款金额="
					+ amt
					+ "元,收款userId="
					+ userId + "\r\n";
			WriteFileUtils.writeFile("payBackRecords-", "yyyyMM", logsBaseUrl
					+ "/payServerRecords/payBakRecords/", log, cts);

		} catch (Exception e) {
			logger.error("写金账户回款回调信息文件失败！", e);
		}
		
	}

	@Override
	public String sendPostToFY(String mchnt_txn_ssn, String out_cust_no,
			String in_cust_no, BigDecimal amt) {
		// 金额
		String amtStr = BalanceUtils.chgToFYVal(amt);
				
		Map<String, String> map = new HashMap<String, String>();
		map.put("mchnt_cd", mchnt_cd);
		map.put("mchnt_txn_ssn", mchnt_txn_ssn);
		map.put("out_cust_no", out_cust_no);
		map.put("in_cust_no", in_cust_no);
		map.put("amt", amtStr);
		map.put("contract_no", "");
		map.put("rem", "");
		map = MapSortUtil.sortMapByKey(map);
		String pathUrl = pathBaseUrl + "/transferBu.action";
		String resultStr =  FYApiUtil.sendPostToFYUtils(map, jzhBaseUrl, pathUrl);
		
		return resultStr;
	}


	@Override
	public Boolean updPaybackResult(String mchnt_txn_ssn, Boolean result) {
		
		logger.info("回款划拨 mchnt_txn_ssn = {}, result={}", mchnt_txn_ssn, result);
		
		if(!result){
			logger.info("回款划拨, 回款失败，停止更新信息 updPaybackResult-- mchnt_txn_ssn ={}", mchnt_txn_ssn);
			return false;
		}
		
		String paybackOrderMsgStr = this.getPaybackRecordFromRedis(mchnt_txn_ssn);
		
		if(StringHelper.isEmpty(paybackOrderMsgStr)){
			logger.info("回款划拨, 流水号在redis中不存在，将停止回款划拨 updPaybackResult-- mchnt_txn_ssn ={}", mchnt_txn_ssn);
			return false;
		}
		
		PaybackOrderMsg paybackOrderMsg =  JsonUtils.toBean(paybackOrderMsgStr, PaybackOrderMsg.class);
		
		logger.error("回款划拨 PaybackOrderMsg={} ", paybackOrderMsg.toString());
		
		Long orderId = paybackOrderMsg.getOrderId();
		
		//如划拨成功，则更改订单确认状态
		logger.info("回款划拨成功 step01，更改订单的回款状态 updPaybackResult-- orderId={}", orderId);
		orderJpaService.updateOrderToPayback(orderId, ConstantOrderStatus.PAY_STATUS_PAYBACK, ConstantOrderStatus.CONFIRM_STATUS__PAYBACK);
		
		//将回款订单从待回款订单列表中删除
		logger.info("回款划拨成功step02, 将订单记录从待回款列表中删除 updPaybackResult-- orderId={}", orderId);
		orderHelperService.delPaybackOrderFromRedis(orderId, paybackOrderMsgStr); ;  	
		
		//将回款订单从redis中删除
		logger.info("回款划拨成功step03, 将订单记录从redis中删除  updPaybackResult-- orderId={}", orderId);
		delPaybackRecordFromRedis(mchnt_txn_ssn);
		
		return true;
	}


	@Override
	public void writeProductFile(String responseCode, Long orderId,
			String in_cust_no, String out_cust_no, BigDecimal amt, Long userId,
			Long productId) {
		try {
			amt = amt.divide(new BigDecimal(100));
			Long cts = System.currentTimeMillis();
			String log = DateUtil
					.transferLongToDate("yyyy-MM-dd HH:mm:ss", cts)
					+ "----金账户回款回调信息:  responseCode = "
					+ responseCode
					+ ",orderId = "
					+ orderId
					+ ",收款账户 = "
					+ in_cust_no
					+ ",付款账户 = "
					+ out_cust_no
					+ ",回款金额="
					+ amt
					+ "元,收款userId="
					+ userId + "\r\n";
			WriteFileUtils.writeFile("payBackRecords-"+productId, "yyyyMM", logsBaseUrl
					+ "/payServerRecords/payBakRecords/", log, cts);

		} catch (Exception e) {
			logger.error("写金账户回款回调信息文件失败！", e);
		}
		
	}
	
	
	 
	
	
	 

}
